Proposal of May 13, 2014
The following is a list of proposed changes for the development of Super Mario Limitless. These changes are proposed by User:Celarix1 on Tuesday, May 13, 2013. Sprite States: From Any String to Standardized States Main Page: Sprite State ' Proposal: ''Change the state of sprites from a string to a SpriteState enumeration. Sprite states are stored in their sprite as a string property. This was to allow the sprite to have any given state, and it would allow custom sprites to define their own states. When sprites interact with other sprites through collision or other means, they would look at each other's states to determine which action to take. However, if the state is not a known state, the sprite may not be able to properly react, and the sprite's behavior cannot be modified directly. This proposed change will add a SpriteState enumeration that defines several fundamental states for any given sprite. Sprites can then safely inspect the state of any sprite interacting with it and behave in any way. The states are as follows: *'''Default: This will be the state that sprites spend most of their time in. *'Stunned:' This state is applied to sprites like stomped Koopas or SMW Goombas that have been temporarily stunned by the player. *'Projectile:' Sprites in this state will damage other sprite and breakable tiles it collides with. *'ProjectileFire: '''This state denotes a fire-based projectile sprite. Other sprites and tiles may wish to react differently to this state. *'ProjectileIce:' This state denotes an ice-based projectile sprite. Other sprites and tiles may wish to react differently to this state. *'Dead:''' This state applies to sprites that have been killed. These sprites should always be ignored by other sprites. The contents of this enumeration can be changed at any time. Changes will usually involve states being added; removing states would require exceptional circumstances. Sprite Damage A Damage method will be added to sprites. This method will be abstract, meaning that sprites will have to define their own damage behavior. For instance, the method might instantly set the sprite's state to Dead, or it might reduce the hit points of the sprite. The Damage method should be called by sprites that cause damage to other sprites. For instance, say a spinning Koopa hit a Goomba. The Koopa would call the Damage method on the Goomba instead of the Goomba checking the Koopa's state and calling Damage on itself. Revisions to Collision *The RestingTile property of sprites will now return the tile returned by the GetTileAtPosition method for the point one pixel beneath the bottom-center point of the sprite. *The IsOnGround property of sprites will now return true if the RestingTile property is non-null AND the vertical velocity isn't upward, false if otherwise. *The collision method will now perform the following code before checking for vertical collisions: #If the sprite is on the ground, get the top pixel of the resting tile with the X-coordinate of the bottom-center point of the sprite. #Set the Y position of the sprite to the top pixel minus the sprite's height. *Finally, gravity will only be applied if IsOnGround is false. Defining the Player Model The player is an advanced sprite that is controllable by the user via keyboard or mouse input.. The player moves through the level, overcoming obstacles and defeating the enemies in the level, eventually reaching the goals at the end of levels or the bosses at the end of boss levels. Player Actions Players can perform the following actions: *Walking: The player can walk either left or right. *Running: The player can run either left or right at a speed faster than walking. *Jumping: The player can jump in the air to overcome obstacles or avoid or attack enemies. The height the player jumps depends on their velocity. *Spin Jump: The player can spin-jump in the air. This allows the player to crush weaker enemies or safely stomp on enemies with damaging shells. Spin jumps are always lower than jumps. *Duck: The player can duck to slide under small gaps or to hide. *Ground Pound: The player, while in the air, can flip end over end and quickly plunge to the ground. Direct impact will break certain blocks and destroy many enemies. Multiple players ground pounding synchronously will cause a wave to emanate, knocking down all on-screen coins and killing most on-screen enemies. *In-Air Turn: While in the air, the player can spin once to slightly slow their fall for a short amount of time. This will give the player a slight advantage in jump distance. These actions are mapped to Input Actions and can be remapped by the user. Players and Assemblies The base type for Players is the Player abstract class in the SMLimitless.Sprites namepsace. The main update loop of the player first checks the input manager to see what the current input state it. If any input actions are being triggered, the player uses these input actions to apply the proper action to the player. For instance, if the Right key is down, this will trigger the Right input action. The player will then apply the walking acceleration to itself until the maximum walking speed has been reached. Like other sprites, player classes derive from the base Player type. The primary differences between players has mostly to do with graphics and aspects of physics - one player may accelerate faster than another, but might also have less friction. As a result, all Player properties that have to do with player physics will have protected setters to allow deriving player lasses to change the physics of themselves. Also like other sprites, these player classes are contained within separate assemblies. Players from any assembly are capable of playing in any level, but they will not be affected by powerups unless there is specific code to handle it. Player Graphics There are many different sets of graphics for players, including idle, walking, running, and jumping. Each set of graphics is an animated graphics object with a certain set of frames. Every time the player's action state changes, the graphics set changes as well, usually starting with the first frame in the set. The speed of the graphic may change; for instance, a running player will accelerate to top speed, and the graphic will accelerate with the player. The code for each player will handle the changing sets of graphics and their speed. The graphics file for the player should be stored as a separate set of animated graphics objects, one for each set. These can be stored as the sprite developer wishes. Powerups A powerup is a sprite that changes the state of a player from weaker to stronger. Powerups usually give the player an additional hit-point, and if a powered-up player takes damage, they typically lose the powerup state. Powerups also give the player an extra ability, such as shooting fireballs, temporary flight while at speed, or the ability to turn into a statue for a few seconds. The range of powerups throughout the Mario series is pretty wide, with many powerups giving many different abilties. Defining a generalized, extensible model for powerups is very important for future developers to create a wide variety of powerup states. At its core, a powerup is essentially a modification of player behavior, or more specifically, an addition to a player's abilities. The primary things that a powerup changes are hit points, player graphics, and the addition of a special ability. The base type for powerup states is PowerupState, also in the SMLimitless.Sprites namespace. There is one powerup state for each affected player for each powerup. To avoid mass code duplication, each powerup might have a static base class or a helper class that handles most of the logic and then the player-based powerup classes merely store the player-specific code. If a player picks up a powerup for which there is no powerup class for that player, there will be no effect. To add new powerups to players in other assemblies, the developer will first create separate player-specific classes for the players he wants to add the powerup to. He then queries a method in GameServices that gives him the pool of all loaded players by their simple name. If the players are present, he can call another method in GameServices that registers his powerup classes for the players and links them to a powerup sprite by the sprite's full type name. He must also register the new player graphics for that powerup or link to an existing set of player graphics. To add existing powerups to a new player, the developer creates player-specific classes for the new powerups to add. She then calls the same methods to register the powerups to the player using the player-specific classes, powerup sprite full type name, and player graphics set. Game Sessions Single Levels, Levelpacks, and Episodes A single level can be launched by the user through a file dialog from the main menu. The user can then play through the single level until they either clear the exit or quit manually. Defined below is the behavior when the player dies. A levelpack is a group of single levels. The user can launch a levelpack through the same file dialog on the main menu, and is presented with a list of levels to select from. The user can play through the levels in order or in any order, and can replay levels as many times as they like. An episode is a full-level game type, featuring worlds. Game Session Properties The game session defines certain properties about the current gameplay, including the number of lives the player has, the number of coins, which levels are cleared, and other things. The base properties are as follows: *Game Type: Either single level, level pack, or episode. *Level List: If the game type is "level pack", this list defines the relative file paths to all the level files in the order they appear on the list. This property is null otherwise. *Player Lives Type: Defines how the game treats player lives - see below. *Initial Lives: The number of lives that each player receives at the start of the game and on each continue. This number is ignored if the Player Lives Type is "Unlimited". *Maximum Lives: The maximum number of lives that players can collect. This number is ignored if the Player Lives Type is "Unlimited". *Game Over Behavior: Defines the behavior of the game when a player loses all their lives - see below. *Allowed Players: A list of strings containing player names. These players are the only ones allowed to play in this game, *Player States: A list containing the number of lives, continues used, individual number of coins, and the powerup state for each player. *Coins: The total number of collected coins during the game. *Points: The total number of points scored during the game. *Level Midway Flags: A list containing which midpoint flags have been cleared in each level. *Player World Positions: A list containing the world map and position on the world map of each player in the game. Applies only to episodes; this property is otherwise null. *World Path Revealed States: A list containing a flag for each world path and level tile that determines if it has been revealed. Additionally, game session files contain another copy of themselves within, this one being the initial game session state. This state defines all the original values for the game session. Player Lives Type One property in the game session file determines how the game treats player lives. The types are as follows: *Classic: The player has a certain maximum number of lives defined by the Maximum Lives property. Each player also has a coin value between 0 and 99 that increases as they collect coins. For every 100 coins, the player receives an extra life. Certain sprites may also give lives to a player - if the player is at the maximum number of lives, they should receives points instead. *Unlimited Lives: Players do not have a life count, and will instead receive an unlimited number of lives. On each death, they will be taken back to the start of the level or the latest cleared midway flag in single levels. In level packs, users are returned to the menu on player death, where they can select another level or resume from the current level. In episodes, users are returned to the world map. The total number of collected coins is displayed at the top of the screen, and coins no longer give extra lives. Sprites that give lives should instead give coins - 50 coins per 1-Up seems like a good conversion rate, but developers can set that as they wish. Game Over Behavior One property in the game session file determines how the game treats game overs. This property only applies if the Player Lives Type property is "classic" and the game type is Level Pack or Episode. The types are as follows: *No Effect: The player who game-overed receives one continue and the initial number of lives, but nothing else is affected. *Reset Last Midway Flag: The last cleared midway flag is reset, meaning gameplay must resume from the midway before that, or the beginning of the level. If no midway flags have been cleared, there is no effect. *Reset All Midway Flags: Same as above, but all flags are reset and players have to start from the beginning of the level. *Reset World: The players start at the beginning of the current world they are in. All levels are reset and all path tiles that weren't initially revealed are hidden again. This has no effect on Level Packs. *Reset Game: The players start from the very beginning, losing all points and coins. The game loads the initial state from the game session. Saving Initial and Current States The GameSession type is ISerializable, meaning that it implements a standard interface for writing itself as a JSON-file. Category:Development Category:Proposals